﻿using MongoDB.Driver;
using Sustainalytics.Entities;
using Sustainalytics.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MongoDB.Driver.Linq;

namespace Sustainalytics.DataLayer
{
    public class MostRecentActivityRepository: IMostRecentActivityRepository
    {
        private MongoClient Client { get; set; }
        private IMongoDatabase Database { get; set; }

        /// <summary>
        /// Ctor.
        /// </summary>
        public MostRecentActivityRepository(string connectionString)
        {
            // DB address
            MongoUrl mongoUrl = MongoUrl.Create(connectionString);

            if (string.IsNullOrWhiteSpace(mongoUrl.DatabaseName))
            {
                throw new ArgumentException("No database specified in the connection string!");
            }

            // Mongo DB client
            this.Client = new MongoClient(mongoUrl);

            // Mongo DB
            this.Database = Client.GetDatabase(mongoUrl.DatabaseName);
        }

        /// <summary>
        /// Repository factory method.
        /// </summary>
        /// <param name="connectionString"> ClientDW Mongo DB connection string. </param>
        /// <returns> Repository instance. </returns>
        public static IMostRecentActivityRepository GetMostRecentActivityRepository(string connectionString)
        {
            MostRecentActivityRepository repo = new MostRecentActivityRepository(connectionString);

            return repo;
        }

        public void Drop()
        {
            this.Database.DropCollection("MostRecentActivity");
        }

        public MostRecentActivity AddMostRecentActivity (MostRecentActivity activity)
        {
            if (activity == null)
            {
                throw new ArgumentNullException("MostRecentActivity is null");
            }

            // add portfolio company
            var activityCol = this.Database.GetCollection<MostRecentActivity>("MostRecentActivity");

            activityCol.InsertOne(activity);
            return activity;
        }

        public MostRecentActivity SaveMostRecentActivity(MostRecentActivity activity)
        {
            if (activity == null)
            {
                throw new ArgumentNullException();
            }
            // update portfolio
            var activityCol = this.Database.GetCollection<MostRecentActivity>("MostRecentActivity");
            IQueryable<MostRecentActivity> activities = activityCol.AsQueryable();

            activityCol.FindOneAndReplace(Builders<MostRecentActivity>.Filter.Eq(x=> x.Id, activity.Id), activity);
            return activity;
        }

        public MostRecentActivity GetUserCompanyMostRecentActivity(List<int> accountUniverses, Guid userId, Guid companyId)
        {
            IQueryable<MostRecentActivity> query = this.Database.GetCollection<MostRecentActivity>("MostRecentActivity").AsQueryable();
            query = query.Where(x => x.UniverseIds.ContainsAny(accountUniverses) && x.UserId == userId && x.CompanyId == companyId);

            var result = query.ToList();

            return result.FirstOrDefault();
        }



        public List<MostRecentActivity> GetMostRecentActivity(List<int> accountUniverses, Guid userId, int? skip, int? take, string[] orderBy = null, bool orderByAsc = true)
        {
            IQueryable<MostRecentActivity> query = this.Database.GetCollection<MostRecentActivity>("MostRecentActivity").AsQueryable();

            query = query.Where(x => x.UniverseIds.ContainsAny(accountUniverses) && x.UserId == userId);

            // ensure order by
            if (!orderByAsc)
                query = query.OrderByDescending(el => el.LastAccessedDate);
            else
                query = query.OrderBy(el => el.LastAccessedDate);

            if (skip.HasValue)
            {
                query = query.Skip(skip.Value);
            }

            if (take.HasValue)
            {
                query = query.Take(take.Value);
            }

            return query.ToList();
        }
    }
}
